package org.expressme.webwind;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * DispatcherServlet must be mapped to root URL "/". It handles ALL requests
 * from clients, and dispatches to appropriate handler to handle each request.
 * 
 * @author Michael Liao (askxuefeng@gmail.com)
 */
public class DispatcherServlet extends GenericServlet {

	static final Logger log = Logger.getLogger(DispatcherServlet.class
			.getName());

	private static final long serialVersionUID = 1L;
	private Dispatcher dispatcher;
	private StaticFileHandler staticFileHandler;

	@Override
	public void init(final ServletConfig config) throws ServletException {
		super.init(config);
		log.info("Init DispatcherServlet...");

		String dispatcherName = config.getInitParameter("dispatcher");
		if (dispatcherName == null || dispatcherName.equals("")) {
			this.dispatcher = new Dispatcher();
		} else {
			try {
				dispatcher = (Dispatcher) Class.forName(dispatcherName)
						.newInstance();
			} catch (Exception e) {
				log.severe("Init dispatcher failed! Please check the dispatcher name");
				throw new RuntimeException(e);
			}
		}

		this.dispatcher.init(new Config() {
			public String getInitParameter(String name) {
				return config.getInitParameter(name);
			}

			public ServletContext getServletContext() {
				return config.getServletContext();
			}
		});
		this.staticFileHandler = new StaticFileHandler(config);
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp)
			throws ServletException, IOException {
		HttpServletRequest httpReq = (HttpServletRequest) req;
		HttpServletResponse httpResp = (HttpServletResponse) resp;
		String method = httpReq.getMethod();
		if ("GET".equals(method) || "POST".equals(method)) {
			if (!dispatcher.service(httpReq, httpResp))
				staticFileHandler.handle(httpReq, httpResp);
			return;
		}
		httpResp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
	}

	@Override
	public void destroy() {
		log.info("Destroy DispatcherServlet...");
		this.dispatcher.destroy();
	}

}
